"""
PlumeSoft 量化代码库
作者：PlumeSoft
用途：贝叶斯选股炼丹炉
"""

import os
import sys

# 获取当前 py 文件所在的目录
current_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 将当前目录添加到 import 搜索目录中
sys.path.append(current_dir)

import threading
import time
import warnings
import pandas as pd
from glob import glob
from optuna_dashboard._app import create_app
from optuna_dashboard.artifact._backend_to_store import to_artifact_store
from bottle import run
import webbrowser
from program.plumesoft_bys.bys_upgrade import daily_check_app_upgrade, print_copyright
import program.plumesoft_bys.bys_config as bys_cfg
from program.plumesoft_bys.multi_task_storage import MultiTaskStorage, CompositeStorage

warnings.filterwarnings("ignore")

# 数据文件名称，如果为 None 或不存在，将自动搜索数据目录下所有文件
storage_name = None
# 可视化面板地址
dashboard_host = "localhost"
dashboard_port = 8090
# 自动打开面板网址
dashboard_auto_open = True
dashboard_auto_open_delay = 3
# 安静无日志模式
quiet_mode = False

def get_storage_name():
    # 获取数据文件名称
    if storage_name is not None and os.path.isfile(storage_name):
        return storage_name

    print("没有定义有效的数据文件路径，正在搜索数据文件...\n")
    files = sorted(
        glob(os.path.dirname(bys_cfg.data_path) + '/**/内部数据.pkl', recursive=True) +
        glob(os.path.dirname(bys_cfg.data_path) + '/**/内部数据_批量.csv', recursive=True))
    for n, file in enumerate(files):
        print(f"[{n+1}].{file}")
    print("\n请输入序号指定要使用的数据文件，或者输入完整的数据文件全路径：")
    instr = input("序号或文件名:")
    if instr.isdigit() and int(instr) > 0 and int(instr) <= len(files):
        filename = files[int(instr) - 1]
    elif os.path.isfile(instr):
        filename = instr
    else:
        print("无效的输入！")
        exit(1)

    return filename

def create_storage(filename: str):
    if filename.endswith(".csv"):
        df = pd.read_csv(filename, encoding='gbk')
        df.sort_values(by=['综合得分'], ascending=False, inplace=True, ignore_index=True)
        storage_dict = {}
        for n, rec in enumerate(df.to_records()):
            name = f"{rec['炼丹策略']}_排名{n+1:03n}_第{rec['轮次']:03n}轮_炼丹分{rec['炼丹得分']:.2f}_综合分{rec['综合得分']:.2f}"
            path = os.path.join(os.path.dirname(filename), rec['内部数据'])
            storage_dict[name] = MultiTaskStorage(path, None)
        storage = CompositeStorage(storage_dict)
    else:
        storage = MultiTaskStorage(filename, None)
    return storage

def open_url(url):
    time.sleep(dashboard_auto_open_delay)
    webbrowser.open(url)
    
def run_dashboard(filename):
    # 创建 Web 应用
    store = to_artifact_store(None)
    storage = create_storage(filename)
    app = create_app(storage, artifact_store=store)

    # 后台线程延时自动打开网址
    if dashboard_auto_open:
        url = f'http://{dashboard_host}:{dashboard_port}'
        threading.Thread(target=open_url, args=(url,), daemon=True).start()

    # 运行 Web 服务器
    run(app, host=dashboard_host, port=dashboard_port, quiet=quiet_mode)


if __name__ == "__main__":
    print_copyright()

    # 每天检查一次软件更新
    daily_check_app_upgrade()

    filename = get_storage_name()

    run_dashboard(filename)
